//
// Created by tang on 23-3-26.
//

#ifndef PIINFO_MATHEMATICS_HPP
#define PIINFO_MATHEMATICS_HPP

#include "sdk_config.h"

struct vec2 {
    union {
        float data[2];
        struct {
            float x,y;
        };
        struct {
            float r,g;
        };
    };
};

struct vec3 {
    union {
        float data[3];
        struct {
            float x,y,z;
        };
        struct {
            float r,g,b;
        };
    };
};

struct vec4 {
    union {
        float data[4];
        struct {
            float x,y,z,w;
        };
        struct {
            float r,g,b,a;
        };
    };
};

template <typename T, typename F> requires requires(T a) { sizeof(a.data); }
inline T operator*(const T &t, F ratio)
{
    T result{t};
    for (auto &x: result.data) {
        x *= ratio;
    }
    return result;
}

template <typename T, typename F> requires requires(T a) { sizeof(a.data); }
inline T operator/(const T &t, F ratio)
{
    T result{t};
    for (auto &x: result.data) {
        x /= ratio;
    }
    return result;
}

template <typename T> requires requires(T a) { sizeof(a.data); }
inline T operator+(const T &l, const T &r)
{
    T result{};
    for (int i=0; i<sizeof(result.data)/sizeof(result.data[0]); ++i)
    {
        result.data[i] = l.data[i] + r.data[i];
    }
    return result;
}

template <typename T> requires requires(T a) { sizeof(a.data); }
inline T operator-(const T &l, const T &r)
{
    T result{};
    for (int i=0; i<sizeof(result.data)/sizeof(result.data[0]); ++i)
    {
        result.data[i] = l.data[i] - r.data[i];
    }
    return result;
}

#endif  // PIINFO_MATHEMATICS_HPP
